<?

class ExceptionHandler {


    /**
     * Logger */
    private $log;


    // ----------------------------------------------------------- Constructors


    public function __construct() {
        $this->log =& LoggerManager::getLogger("ExceptionAction");
    }


    // --------------------------------------------------------- Public Methods


    /**
     * <p> Handle the Exception. Return the ActionForward instance (if any)
     * returned by the called ExceptionHandler. </p>
     *
     * @param ex           The exception to handle
     * @param ae           The ExceptionConfig corresponding to the exception
     * @param mapping      The ActionMapping we are processing
     * @param formInstance The ActionForm we are processing
     * @param request      The servlet request we are processing
     * @param response     The servlet response we are creating
     * @return The <code>ActionForward</code> instance (if any) returned by
     *         the called <code>ExceptionHandler</code>.
     * @throws ServletException if a servlet exception occurs
     * @since Struts 1.1
     */
    public function execute(Exception $e, ExceptionConfig &$config,
        ActionConfig &$mapping, &$form, Request &$request, Response &$response) {

        $this->log->error("ExceptionHandler executing for exception " . $e);

        // Build the forward from the exception mapping if it exists
        // or from the form input
        if ($config->getPath() !== null) {
            $forward = new ForwardConfig(
                array("path"=>$config->getPath()));
        } else {
            $forward = $mapping->getInputForward();
        }

        require_once("mvc/action/ActionMessage.php");
        $error = new ActionMessage($config->getKey(), $e->getMessage());
        $property = $error->getKey();

        // Store the exception
        $request->setAttribute(MVC::EXCEPTION_KEY, $e);
        $request->setAttribute(MVC::MAPPING_KEY, $mapping);
        $this->storeException($request, $property, $error, $forward, $config->getScope());

        if (!$response->isCommitted()) {
            return $forward;
        }

        $this->log->error("Response is already committed, so forwarding will not work."
            . " Attempt alternate handling.");

        return null;

    }


    // --------------------------------------------------------- Protected Methods


    /**
     * <p>Default implementation for handling an <code>ActionMessage</code>
     * generated from an <code>Exception</code> during <code>Action</code>
     * delegation. The default implementation is to set an attribute of the
     * request or session, as defined by the scope provided (the scope from
     * the exception mapping). An <code>ActionMessages</code> instance is
     * created, the error is added to the collection and the collection is set
     * under the <code>Globals.ERROR_KEY</code>.</p>
     *
     * @param request  The request we are handling
     * @param property The property name to use for this error
     * @param error    The error generated from the exception mapping
     * @param forward  The forward generated from the input path (from the
     *                 form or exception mapping)
     * @param scope    The scope of the exception mapping.
     * @since Struts 1.2
     */
    protected function storeException(Request $request, $property,
        ActionMessage $error, ForwardConfig $forward, $scope) {

        require_once("mvc/action/ActionMessages.php");
        $errors = new ActionMessages();
        $errors->add($property, $error);
        
        if ("request" == $scope) {
            $request->setAttribute(MVC::ERROR_KEY, $errors);
        } else {
            $request->getSession()->setAttribute(MVC::ERROR_KEY, $errors);
        }

    }

}
?>